import { error, JsonAsset, log, resources, warn } from "cc";
import { Engine } from "../Engine";
import Logger from "../utils/Logger";

export enum LanguageEvent {
    /** 语种变化事件 */
    CHANGE = "LanguageEvent.CHANGE",
    /** 语种资源释放事件 */
    RELEASE_RES = "LanguageEvent.RELEASE_RES",
}
const DEFAULT_LANGUAGE = "zh";

class LanguageManager {
    private _currentLang: string = ""; // 当前语言
    private _supportLanguages: Array<string> = ["zh", "en", "tr"]; // 支持的语言
    // 默认资源文件目录
    private _langjsonPath: string = "i18n/json";
    private _langTexturePath: string = "i18n/textures";

    private _languageMap!: any; // 当前语言列表

    private static _instance: LanguageManager;

    static getInstance() {
        if (!this._instance) {
            this._instance = new LanguageManager();
        }

        return this._instance;
    }

    constructor() {}

    /** 设置多语言系统支持哪些语种 */
    public set supportLanguages(supportLanguages: Array<string>) {
        this._supportLanguages = supportLanguages;
    }

    /**
     * 获取当前语种
     */
    public get currentLanguage(): string {
        return this._currentLang;
    }

    /**
     * 获取支持的多语种数组
     */
    public get languages(): string[] {
        return this._supportLanguages;
    }

    public isExist(lang: string): boolean {
        return this.languages.indexOf(lang) > -1;
    }

    /**
     * 改变语种，会自动下载对应的语种，下载完成回调
     * @param language
     */
    public setLanguage(language: string) {
        if (!language) {
            language = DEFAULT_LANGUAGE;
        }
        language = language.toLowerCase();
        let index = this.languages.indexOf(language);
        if (index < 0) {
            warn("当前不支持该语种" + language + " 将自动切换到 zh 语种！");
            language = DEFAULT_LANGUAGE;
        }
        if (language === this._currentLang) {
            return;
        }

        this.loadLanguageAssets(language, (lang: string) => {
            Logger.log(`当前语言为【${language}】`);
            this._currentLang = language;
            const languageJson = Engine.resManager.get(this._langjsonPath + "/" + this._currentLang) as JsonAsset;
            this._languageMap = languageJson.json;
            Engine.eventManager.emit(LanguageEvent.CHANGE, lang);
        });
    }

    /**
     * 设置多语言资源目录
     * @param langjsonPath 多语言json目录
     * @param langTexturePath 多语言图片目录
     */
    public setAssetsPath(langjsonPath: string, langTexturePath: string) {
        this._langTexturePath = langjsonPath;
        this._langTexturePath = langTexturePath;
    }

    /**
     * 根据data获取对应语种的字符
     * @param labId
     * @param arr
     */
    public getLangByID(key: string): string {
        return this._languageMap[key] as string | "unknow";
    }

    /**
     * 翻译数据  包含层级的key
     * @param key
     */
    public t(key: string) {
        if (!this._languageMap) {
            return;
        }
        const searcher = key.split(".");
        let data = this._languageMap;
        for (let i = 0; i < searcher.length; i++) {
            data = data[searcher[i]];
            if (!data) {
                return "";
            }
        }

        return data || "";
    }

    /**
     * 下载对应语言包资源
     * @param lang 语言标识
     * @param callback 下载完成回调
     */
    public loadLanguageAssets(lang: string, callback: Function) {
        lang = lang.toLowerCase();
        const lang_texture_path = `${this._langTexturePath}/${lang}`;
        const lang_json_path = `${this._langjsonPath}/${lang}`;
        let loadNum = 2;
        Engine.resManager.loadDir(lang_texture_path).then(() => {
            loadNum--;
            if (loadNum === 0) {
                callback(lang);
            }
        });
        Engine.resManager.loadPath(lang_json_path).then(() => {
            loadNum--;
            if (loadNum === 0) {
                callback(lang);
            }
        });
    }
    /**
     * 释放某个语言的语言包资源包括json
     * @param lang
     */
    public releaseLanguageAssets(lang: string) {
        lang = lang.toLowerCase();
        const lang_texture_path = `${this._langTexturePath}/${lang}`;
        resources.release(lang_texture_path);
        Logger.log(lang_texture_path, "释放语言图片资源");

        const lang_json_path = `${this._langjsonPath}/${lang}`;
        resources.release(lang_json_path);
        Logger.log(lang_json_path, "释放语言文字资源");

        Engine.eventManager.emit(LanguageEvent.RELEASE_RES, lang);
    }
}

export const i18n = LanguageManager.getInstance();
